#pragma once
#include <vector>
#include "InetAddr.hpp"
#include <sys/types.h>
#include <sys/socket.h>
#include "threadpool.hpp"
#include <functional>
#include <mutex>

using task_t = std::function<void(void)>;

class MessageRoute
{
public:
    void AddUsr(const InetAddr &usr)
    {
        std::lock_guard<std::mutex>lock(_mtx);//加锁保护公共资源_usr
        for (auto it = _usr.begin(); it != _usr.end(); it++)
        {
            if (*it == usr)
            {
                return;
            }
        }
        _usr.push_back(usr);
    }
    void DelUsr(const InetAddr &usr)
    {
        std::lock_guard<std::mutex>lock(_mtx);//确保线程安全
        for (auto it = _usr.begin(); it != _usr.end(); it++)
        {
            if (*it == usr)
            {
                _usr.erase(it);
                return;
            }
        }
    }

    void routeTask(int sockfd, std::string &message)
    {
        std::lock_guard<std::mutex>lock(_mtx);
        for (auto &u : _usr)
        {
            sendto(sockfd, message.c_str(), sizeof(message.c_str()), 0, (struct sockaddr *)&u.Addr(), sizeof(u.Addr()));
        }
    }

    void route(int sockfd, const std::string &message, const InetAddr &who) // 消息转发
    {
        AddUsr(who);
        if (message == "q")
        {
            DelUsr(who);
        }
        task_t task=std::bind(&MessageRoute::routeTask,this,sockfd,message);
        ThreadPool<task_t>::GetInstance()->push(task);
        Log(DEBUG,"已经放入任务");
    }

private:
    std::vector<InetAddr> _usr;
    std::mutex _mtx;
};